package com.ruoyi.ams.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import com.ruoyi.ams.domain.AmsAssetBorrow;
import com.ruoyi.ams.domain.bo.BorrowSearchVo;
import com.ruoyi.ams.service.*;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.KeyValueVo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsAssetType;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.domain.model.AmsOwnAsset;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 资产借用归还Controller
 * 
 * @author yfkj
 * @date 2022-05-16
 */
@RestController
@RequestMapping("/ams/borrow")
public class AmsAssetBorrowController extends BaseController
{
    @Autowired
    private IAmsAssetBorrowService amsAssetBorrowService;
    @Autowired
    private IAmsAssetTypeService amsAssetTypeService;
    @Autowired
    private IAmsOwnAddressService amsOwnAddressService;
    @Autowired
    private AmsReusingService amsReusingService;
    @Autowired
    private IAmsOwnAssetService amsOwnAssetService;

    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
    @Autowired
    private SysUserController userController;
    @Autowired
    private SysDeptController deptController;
    private QueryWrapper<AmsAssetBorrow> buildSearchQueryWrapper(BorrowSearchVo searchVo) {
        QueryWrapper<AmsAssetBorrow> wrapper = new QueryWrapper<>();
        if (searchVo.getBorrowStatus() != null) {
            wrapper.eq(AmsAssetBorrow.BORROW_STATUS, searchVo.getBorrowStatus());
        }
        if (searchVo.getCode() != null) {
            List<AsmsAssetFullInfo> assetFullInfos = asmsAssetFullInfoService
                    .list(new QueryWrapper<AsmsAssetFullInfo>()
                            .like(AsmsAssetFullInfo.ASSET_CODE, searchVo.getCode())
                            .or().like(AsmsAssetFullInfo.SN, searchVo.getCode()));
            if (assetFullInfos .size()>0) {
                wrapper.in(AmsAssetBorrow.ASSET_ID, assetFullInfos.stream().map(AsmsAssetFullInfo::getAssetId).toArray());
            }
        }
        if(searchVo.getAssetTypeId()!=null){
            wrapper.eq(AmsAssetBorrow.ASSET_TYPE_ID, searchVo.getAssetTypeId());
        }
        if(searchVo.getUserId()!=null){
            wrapper.eq(AmsAssetBorrow.USER_ID, searchVo.getUserId());
        }
        return wrapper;
    }
    /**
     * 查询资产借用归还列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:list")
    @ApiOperation(value = "获取资产借用归还列表")
    @GetMapping("/getAmsAssetBorrowList")
    public TableDataInfo getAmsAssetBorrowList(BorrowSearchVo searchVo)
    {
        QueryWrapper<AmsAssetBorrow> wrapper = buildSearchQueryWrapper(searchVo);
        wrapper.orderByDesc(AmsAssetBorrow.BORROW_ID);
        startPage();
        List<AmsAssetBorrow> list = amsAssetBorrowService.list(wrapper);

        CompletableFuture<R<Map<Long, SysUser>>> future1 = CompletableFuture.supplyAsync(() ->
                userController.getAllUsers());

        CompletableFuture<R<Map<Long, SysDept>>> future2 = CompletableFuture.supplyAsync(() ->
                deptController.getAllDeptsMap());

        CompletableFuture<List<AmsAssetType>> future3 = CompletableFuture.supplyAsync(() ->
                amsAssetTypeService.list(new QueryWrapper<AmsAssetType>()
                        .select(AmsAssetType.ASSET_TYPE_ID, AmsAssetType.ASSET_TYPE_NAME)));

        CompletableFuture<List<AsmsAssetFullInfo>> future4 = CompletableFuture.supplyAsync(() ->
                asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                        .select(AsmsAssetFullInfo.ASSET_ID, AsmsAssetFullInfo.ASSET_CODE)));

        CompletableFuture<List<AmsOwnAddress>> future5 = CompletableFuture.supplyAsync(() ->
                amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>()
                        .select(AmsOwnAddress.ADDRESS_ID, AmsOwnAddress.FULL_NAME)));

        HashMap<Long, String> typeMap = new HashMap<>();
        HashMap<Long, String> assetInfoMap = new HashMap<>();
        HashMap<Long, String> addressMap = new HashMap<>();
        R<Map<Long, SysUser>> allUsers = new R<>();
        R<Map<Long, SysDept>> allDeptsMap = new R<>();
        List<AmsAssetType> types = new ArrayList<>();
        List<AsmsAssetFullInfo> fullInfos = new ArrayList<>();
        List<AmsOwnAddress> addresses = new ArrayList<>();
        try {
            allUsers = future1.get();
            if (allUsers.getCode() == R.FAIL) {
                return amsReusingService.resovleError();
            }
            allDeptsMap = future2.get();
            if (allDeptsMap.getCode() == R.FAIL) {
                return amsReusingService.resovleError();
            }
            types = future3.get();
            fullInfos = future4.get();
            addresses = future5.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        for (AmsAssetType type : types) {
            typeMap.put(type.getAssetTypeId(), type.getAssetTypeName());
        }

        for (AsmsAssetFullInfo fullInfo : fullInfos) {
            assetInfoMap.put(fullInfo.getAssetId(), fullInfo.getAssetCode());
        }

        for (AmsOwnAddress address : addresses) {
            addressMap.put(address.getAddressId(), address.getFullName());
        }

        Map<Long, SysUser> userMap = allUsers.getData();
        Map<Long, SysDept> deptMap = allDeptsMap.getData();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy.MM.dd");

        for (AmsAssetBorrow borrow : list) {
            if (borrow.getUserId() != null) {
                SysUser sysUser = userMap.get(borrow.getUserId());
                if (sysUser != null) {
                    borrow.setUserName(sysUser.getNickName());
                }
            }
            if (borrow.getDeptId() != null) {
                SysDept sysDept = deptMap.get(borrow.getDeptId());
                if (sysDept != null) {
                    borrow.setDeptName(sysDept.getDeptFullName());
                }
            }
            if (borrow.getAddressId() != null) {
                borrow.setAddressName(addressMap.get(borrow.getAddressId()));
            }
            if (borrow.getReturnAddressId() != null) {
                borrow.setReturnAddressName(addressMap.get(borrow.getReturnAddressId()));
            }
            if (borrow.getAssetTypeId() != null) {
                borrow.setAssetTypeName(typeMap.get(borrow.getAssetTypeId()));
            }
            if (borrow.getAssetId() != null) {
                borrow.setAssetCode(assetInfoMap.get(borrow.getAssetId()));
            }
            if (borrow.getChargerId() != null) {
                SysUser sysUser = userMap.get(borrow.getChargerId());
                if (sysUser != null) {
                    borrow.setChargerName(sysUser.getNickName());
                }
            }
            if (borrow.getReturnChargerId() != null) {
                SysUser sysUser = userMap.get(borrow.getReturnChargerId());
                if (sysUser != null) {
                    borrow.setReturnChargerName(sysUser.getNickName());
                }
            }
            if (borrow.getBorrowTime() != null) {
                borrow.setBorrowTimeStr(fmt.format(new Date(borrow.getBorrowTime())));
            }
            if (borrow.getExpectReturnTime() != null) {
                borrow.setExpectReturnTimeStr(fmt.format(new Date(borrow.getExpectReturnTime())));
            }
            if (borrow.getActualReturnTime() != null) {
                borrow.setActualReturnTimeStr(fmt.format(new Date(borrow.getActualReturnTime())));
            }
            if (borrow.getCreateTime() != null) {
                borrow.setCreateTimeStr(fmt.format(new Date(borrow.getCreateTime())));
            }
            if (borrow.getUpdateTime() != null) {
                borrow.setUpdateTimeStr(fmt.format(new Date(borrow.getUpdateTime())));
            }
        }
        return getDataTable(list, 10);
    }



    /**
     * 获取资产借用归还详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:query")
    //@ApiOperation(value = "获取资产借用归还详情")
    @GetMapping(value = "/getAmsAssetBorrowById")
    public AjaxResult getAmsAssetBorrowById(@RequestParam("borrowId") Long borrowId)
    {
        return AjaxResult.success(amsAssetBorrowService.selectAmsAssetBorrowByBorrowId(borrowId));
    }

    /**
     * 新增资产借用归还
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:add")
    @Log(title = "资产借用归还", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增资产借用归还")
    @PostMapping(value = "/addAmsAssetBorrow")
    public AjaxResult addAmsAssetBorrow(@RequestBody AmsAssetBorrow amsAssetBorrow)
    {
        if (amsAssetBorrow.getAssetIds().length == 0) {
            return AjaxResult.error("请至少选择一个资产");
        }

        HashMap<Long, Long> assetIdTypeIdMap = amsReusingService.getAssetIdTypeIdMap();

        List<AmsAssetBorrow> borrows = new ArrayList<>();
        for (Long assetId : amsAssetBorrow.getAssetIds()) {
            AmsAssetBorrow borrow = new AmsAssetBorrow();
            BeanUtils.copyProperties(amsAssetBorrow, borrow);
            borrow.setAssetId(assetId);
            borrow.setSn(amsReusingService.createSn());
            borrow.setCreateTime(System.currentTimeMillis());
            borrow.setAssetTypeId(assetIdTypeIdMap.get(assetId));
            borrows.add(borrow);
        }
        amsOwnAssetService.update(new UpdateWrapper<AmsOwnAsset>().set(AmsOwnAsset.ASSET_STATUS,3).in(AmsOwnAsset.ASSET_ID,amsAssetBorrow.getAssetIds()));
        asmsAssetFullInfoService.update(new UpdateWrapper<AsmsAssetFullInfo>().set(AsmsAssetFullInfo.ASSET_STATUS,3).in(AsmsAssetFullInfo.ASSET_ID,amsAssetBorrow.getAssetIds()));

        amsAssetBorrowService.saveBatch(borrows);
        return AjaxResult.success();
    }
    @PreAuthorize
    @ApiOperation(value = "新增资产退库")
    @PostMapping(value = "/backAmsAssetRequisitionList")
    public AjaxResult backAmsAssetRequisitionList(@RequestBody List<AmsAssetBorrow> borrows)
    {

        Set<Long> assetIds = borrows.stream().map(AmsAssetBorrow::getAssetId).collect(Collectors.toSet());
        amsOwnAssetService.update(new UpdateWrapper<AmsOwnAsset>().set(AmsOwnAsset.ASSET_STATUS,2).in(AmsOwnAsset.ASSET_ID,assetIds));
        asmsAssetFullInfoService.update(new UpdateWrapper<AsmsAssetFullInfo>().set(AsmsAssetFullInfo.ASSET_STATUS,2).in(AsmsAssetFullInfo.ASSET_ID,assetIds));

        amsAssetBorrowService.updateBatchById(borrows);
        return AjaxResult.success();
    }
    /**
     * 修改资产借用归还
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:edit")
    @Log(title = "资产借用归还", businessType = BusinessType.UPDATE)
    //@ApiOperation(value = "修改资产借用归还")
    @PostMapping(value = "/editAmsAssetBorrow")
    public AjaxResult editAmsAssetBorrow(@RequestBody AmsAssetBorrow amsAssetBorrow)
    {
        if (amsAssetBorrow.getAssetIds().length == 0) {
            return AjaxResult.error("请至少选择一个资产");
        }
        List<AmsAssetBorrow> borrows = new ArrayList<>();
        for (Long assetId : amsAssetBorrow.getAssetIds()) {
            AmsAssetBorrow borrow = new AmsAssetBorrow();
            BeanUtils.copyProperties(amsAssetBorrow, borrow);
            borrow.setAssetId(assetId);
            borrow.setUpdateTime(System.currentTimeMillis());
            borrows.add(borrow);
        }
        amsAssetBorrowService.updateBatchById(borrows);
        return AjaxResult.success();
    }

    /**
     * 删除资产借用归还
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:remove")
    @Log(title = "资产借用归还", businessType = BusinessType.DELETE)
	@GetMapping("/removeAmsAssetBorrows")
    public AjaxResult removeAmsAssetBorrows(@RequestParam Long[] borrowIds)
    {
        return toAjax(amsAssetBorrowService.deleteAmsAssetBorrowByBorrowIds(borrowIds));
    }
    @GetMapping("/getAmsAssetBorrowNamesForSelect")
    //@ApiOperation(value = "获取资产借用归还名称列表用于下拉搜索")
    public AjaxResult getAmsAssetBorrowNamesForSelect()
    {
        List<AmsAssetBorrow> list = amsAssetBorrowService.list();//自行加条件
        List<KeyValueVo> resultList = new ArrayList<>();
        for (AmsAssetBorrow amsAssetBorrow: list ) {
            KeyValueVo vo = new KeyValueVo();
            //vo.setKey(it.getId());
            //vo.setValue(it.getName());
            resultList.add(vo);
        }
        return AjaxResult.success(resultList);
    }
    /**
     * 导出资产借用归还列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:borrow:export")
    @Log(title = "资产借用归还", businessType = BusinessType.EXPORT)
    @PostMapping("/exportAmsAssetBorrow")
    public String exportAmsAssetBorrow(HttpServletResponse response, AmsAssetBorrow amsAssetBorrow) throws IOException
    {
        List<AmsAssetBorrow> list = amsAssetBorrowService.selectAmsAssetBorrowList(amsAssetBorrow);
        ExcelUtil<AmsAssetBorrow> util = new ExcelUtil<AmsAssetBorrow>(AmsAssetBorrow.class);
        util.exportExcel(response, list, "资产借用归还数据");
        return "";
    }

}
